﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace DBLGen
{
	[System.Diagnostics.DebuggerDisplay("Method: {Name}")]
	[DefaultProperty("Alias")]
	public sealed class Method
	{
		private Table _table;

		private string _name;
		private string _sqlQuery = string.Empty;
		private string _comments = string.Empty;
		private bool _createMethod = true;
		// new
		CustomAttributesQuery _customAttributesQuery;

		/// <summary>
		/// Gets the table that owns this column.
		/// </summary>
		[Browsable(false)]
		public Table Table
		{
			get
			{
				return _table;
			}
			internal set
			{
				_table = value;
			}
		}

		/// <summary>
		/// Gets or sets the name of the table.
		/// </summary>
		[Category("Method")]
		[DisplayName("Method Name")]
		[Description("The name of the column.")]
		[TypeConverter(typeof(UI.Design.ColumnIdentifierTypeConverter))]
		public string Name
		{
			get
			{
				return _name ?? String.Empty;
			}
			set
			{
				_name = value;
			}
		}
		/// <summary>
		/// Defines Column as Method
		/// </summary>
		[Category("Info")]
		[Description("Custom Method Sql Query")]
		public string SqlQuery
		{
			get
			{
				if (string.IsNullOrEmpty(this._sqlQuery))
				{
					if (this._customAttributesQuery != null)
					{
						this._sqlQuery = this._customAttributesQuery.SQLDisplay;
						return this._customAttributesQuery.SQLDisplay;
					}
					return string.Empty;					
				}
				return this._sqlQuery;
			}
			set
			{
				_sqlQuery = value;
			}
		}
		/// <summary>
		/// Gets or sets the comments about method.
		/// </summary>
		[Category("Info")]
		[Description("Custom Method Description - this will be generated into class.")]
		[DisplayName("Method Comments")]
		public string Comments
		{
			get
			{
				return _comments ?? String.Empty;
			}
			set
			{
				_comments = value;
			}
		}

		[Category("Details")]
		[Description("Defines if the method will be created can be exported.")]
		public bool CreateMethod
		{
			get
			{
				return _createMethod;
			}
			set
			{
				_createMethod = value;
			}
		}
		
		[Category("Method")]
		[Browsable(true)]
		[Description("Create custom sql statement")]
		[DisplayName("Method Query Builder")]
		public CustomAttributesQuery CustomAttributesQuery
		{
			get
			{
				if (_customAttributesQuery == null)
				{
					this._customAttributesQuery = new CustomAttributesQuery(this._table);
					this._customAttributesQuery.SQLDisplay = this.SqlQuery;
				}
				else
				{
					if (this._customAttributesQuery.NeedToSetOwner())
					{
						this._customAttributesQuery.SetOwner(this._table);
						this._customAttributesQuery.SQLDisplay = this.SqlQuery;
					}
						
				}
				return _customAttributesQuery;
			}
			set
			{
				_customAttributesQuery = value;
			}
		}

		#region Xml Persistence

		internal static Method LoadFromXml(XPathNavigator navigator)
		{
			string uri = navigator.NamespaceURI;

			string name = navigator.GetAttribute("name", uri);
			string sqlQuery = navigator.GetAttribute("sqlQuery", uri);

			string comments = null;

			if (navigator.MoveToChild("comments", uri))
			{
				comments = navigator.Value;
				navigator.MoveToParent();
			}

			// CustomAttributes ca = CustomAttributes.LoadXml(navigator);
			CustomAttributesQuery caq = CustomAttributesQuery.LoadXml(navigator);

			Method m = new Method();

			m.Name = name;
			m.SqlQuery = sqlQuery;
			m.Comments = comments;
			// m.CustomAttributes = ca;
			if(caq != null)
				m.CustomAttributesQuery = caq;
			
			return m;
		}

		internal void SaveToXml(XmlWriter writer)
		{
			writer.WriteStartElement("method");
			// database data

			writer.WriteAttributeString("name", Name);
			if (!String.IsNullOrEmpty(SqlQuery))
				writer.WriteAttributeString("sqlQuery", SqlQuery);

			if (!String.IsNullOrEmpty(Comments))
			{
				writer.WriteStartElement("comments");
				writer.WriteCData(Comments);
				writer.WriteEndElement();
			}

			// custom attributes
			CustomAttributesQuery.SaveXml(writer);
			// CustomAttributes.SaveXml(writer);

			writer.WriteEndElement();
		}

		#endregion

	}
}
